package plgcore

import (
	"dgo/MyProj/PrjHttpUtils"
	"dgo/goutils/utils"
	"dgo/plg/plgbase"
	"dgo/plg/plgnet"
	"fmt"
	"gitee.com/ymofen/gobase/golog"
	"gitee.com/ymofen/supervalue"
)

type PlugLocalFileLogger struct {
	PlgBase
	fileName string
	loggerW  *utils.LoggerTypeFileWriter
}

/*
*
// fmt.Sprintf("%s/sys/log/add?id=%s&type=%s", "http://121.36.207.51:9004", PrjConf.APP_UUID, "NETLOCKER")

	{
	   "filename":"$approot$/log/app.log",
	   "format":"[%D %T] [%L] %M (%S)\r\n",
	   "loglvl":"DEBUG",
	   "loglvlop":">=",
	   "maxfilesize":"50M"
	}
*/
func (this *PlugLocalFileLogger) ReloadConf(conf *wrapper.SuperValue) error {
	log0 := utils.Log
	if sflogger, ok := log0.(*utils.SafeLogger); ok {
		logfile := plgbase.ReplacePlaceholderVars(conf.StringByName("filename", ""))
		if len(logfile) > 0 {
			err := utils.ForceCreateFilePath(logfile)
			if err != nil {
				golog.Warnf("创建日志路径异常:%s", err.Error())
			}
		}

		if len(logfile) > 0 && this.fileName != logfile {
			if this.loggerW != nil {
				this.loggerW.Close()
				sflogger.RemoveWriter(this.loggerW)
				this.loggerW = nil
			}
			wr := utils.NewLoggerTypeFileWriter(logfile)
			this.loggerW = wr
			sflogger.AddWriter(wr)
			this.fileName = logfile
		}

		log_fmt := conf.StringByName("format", "")

		if this.loggerW != nil {
			conf.CheckStrFunc("loglvl", func(strv string) {
				log_lvl := utils.LogLvlStr2Lvl(strv)
				opstr := conf.StringByName("loglvlOp", ">=")
				log_op := utils.LogOperaStr2LogOp(opstr)
				this.loggerW.SetLvlFilter(log_lvl, log_op)
				golog.Infof("修改日志配置(%s %s) file:%s", opstr, utils.LogLvlStr(log_lvl), this.fileName)
			})

			if len(log_fmt) > 0 {
				this.loggerW.SetMsgFormat(log_fmt)
			}

			conf.CheckStrFunc("maxfilesize", func(strv string) {
				val := utils.StrToNumSuffix(strv, 1024)
				if val > 0 {
					this.loggerW.ConfigMaxFileSize(val)
				} else {
					this.loggerW.ConfigMaxFileSize(int64(utils.StrToInt64Def(strv, 0)))
				}
			})

			conf.CheckStrFunc("filecachesize", func(strv string) {
				val := utils.StrToNumSuffix(strv, 1024)
				if val > 0 {
					this.loggerW.ConfigFileCacheSize(val)
				} else {
					this.loggerW.ConfigFileCacheSize(int64(utils.StrToInt64Def(strv, 0)))
				}
			})
			return nil
		}

		return nil
	} else {
		return fmt.Errorf("utils.Log:%+v, 非SafeLogger不能进行该日志的创建", log0)
	}
}

func (this *PlugLocalFileLogger) OnHttpStatus(rec *plgnet.PlgHttpRec) (rval interface{}, errcode int, err error) {
	itype := rec.QryAsInt("type", 0)
	if itype == 99 {
		json := wrapper.NewSVObject()
		json.SetKeyValue("logfile", this.fileName)
		if this.loggerW != nil {
			json.SetKeyValue("workerstatus", this.loggerW.GetWorkStatus())
			json.SetKeyValue("file-cachesize", this.loggerW.GetCacheSize())
		}
		json.SetKeyValues("now", utils.NowString())
		if rec.QryAsInt("json", 0) == 1 {
			PrjHttpUtils.ResponseAsJSON(rec.RespW, json.AsJSONStringEx(false, true))
		} else {
			PrjHttpUtils.JSON2TableRec(rec.RespW, "", json.AsJSONString(false))
		}
	} else {
		var sb utils.BytesBuilder
		PrjHttpUtils.AppendIndexBody(&sb, "status", "status?type=99")
		//PrjHttpUtils.AppendIndexBody(&sb, "msglist", "status?type=98&n=100&searchval=")
		//PrjHttpUtils.AppendIndexBody(&sb, "lst", "status?type=1&n=100&searchval=")
		PrjHttpUtils.ResponseBodyHtml(rec.RespW, sb.String())
	}
	return
}

func (this *PlugLocalFileLogger) OnObjectNotify(sender interface{}, notifytype int, data interface{}) (rval interface{}, err error) {
	if notifytype == utils.NOTIFY_TYPE_SETCONF {
		if conf, ok := data.(*wrapper.SuperValue); ok {
			err = this.ReloadConf(conf)
		}
	} else if notifytype == utils.NOTIFY_TYPE_RELEASE {
		if this.loggerW != nil {
			this.loggerW.Close()
			if sflogger, ok := utils.Log.(*utils.SafeLogger); ok {
				sflogger.RemoveWriter(this.loggerW)
			}
			this.loggerW = nil
		}
	}
	return
}

func CreateLoggerFilePlugFunc(args ...interface{}) (rval interface{}, err error) {
	obj := &PlugLocalFileLogger{}
	if len(args) > 0 {
		if str, ok := args[0].(string); ok {
			obj.PlugId = str
		}
	}
	rval = obj
	return
}
